<script lang="tsx" setup>
import { computed, reactive, ref, watch } from 'vue';
import type { FormItemRule, FormRules, NAvatar } from 'naive-ui';
import { useNaiveForm } from '@/hooks/common/form';
import type { DictDataOption } from '@/typings/global';
import type { DeptVO, NoticeVO, PostVO, RoleVO, UserVO } from '@/service/types/system';
import { addNotice, editNotice, getNotice } from '@/service/api/system/notice';
import { optionSelect } from '@/service/api/system/role';
import { getPostSelect as postSelect } from '@/service/api/system/post';
import { deptTreeSelect, getAllUsers } from '@/service/api/system/user';
import { useDebounce } from '@/hooks/common/debounce';
type Model = Pick<
  NoticeVO,
  | 'noticeTitle'
  | 'noticeId'
  | 'immortal'
  | 'filterType'
  | 'deadline'
  | 'filterCondition'
  | 'receiveMode'
  | 'noticeType'
  | 'status'
  | 'noticeContent'
>;
interface Props {
  operateType: NaiveUI.TableOperateType;
  currentId?: string | number | null | unknown;
  sysNoticeType: DictDataOption[];
  sysFilterType: DictDataOption[];
  sysReceiveMode: DictDataOption[];
}
const loading = ref(false);
interface Emits {
  (e: 'submitted'): void;
}
const show = ref<boolean>(false);
const props = defineProps<Props>();
const emit = defineEmits<Emits>();
defineOptions({
  name: 'NoticeForm'
});
const { formRef, validate, restoreValidation } = useNaiveForm();
// const { createRequiredRule } = useFormRules();
const rules: FormRules = {
  noticeTitle: {
    required: true,
    message: '公告标题不能为空',
    trigger: 'blur'
  },
  noticeContent: {
    required: true,
    message: '公告内容不能为空',
    trigger: 'blur'
  },
  filterType: {
    required: true,
    message: '请选择筛选类型',
    trigger: 'blur'
  },
  noticeType: {
    required: true,
    message: '请选择公告类型',
    trigger: 'blur'
  },
  receiveMode: {
    type: 'array',
    trigger: 'change',
    required: true,
    message: '请选择通知方式'
  },
  filterCondition: {
    required: true,
    type: 'array',
    message: '筛选条件',
    trigger: ['blur', 'change']
  },
  immortal: {
    required: true,
    validator(rule: FormItemRule, value: string) {
      if (!value) {
        return new Error('请选择是否永久有效');
      }
      if (value === '1') {
        // 校验失效时间
        if (!model.deadline) {
          return new Error('请选择失效时间');
        }
      }
      return true;
    },
    trigger: ['blur']
  }
};

const title = computed(() => {
  const titles: Record<NaiveUI.TableOperateType, string> = {
    add: '新增客户端',
    edit: '修改客户端'
  };
  return titles[props.operateType];
});
const visible = defineModel<boolean>('visible', {
  default: false
});
const currentModelData = ref<NoticeVO>();
const model: Model = reactive(createDefaultModel());
function createDefaultModel(): Model {
  return {
    status: '0',
    noticeTitle: '',
    noticeId: '',
    filterCondition: null,
    receiveMode: '',
    // 添加缺失的属性
    immortal: '0',
    filterType: null,
    deadline: null,
    noticeType: null,
    noticeContent: ''
  };
}
const getClientById = async (id: number) => {
  show.value = true;
  const { error, data } = await getNotice(id);
  if (!error) {
    currentModelData.value = data?.data;
  }
  show.value = false;
};

async function handleInitModel() {
  Object.assign(model, createDefaultModel());
  if (props.operateType === 'edit' && props.currentId) {
    await getClientById(props.currentId as number);
    Object.assign(model, currentModelData.value);
  }
}
watch(visible, () => {
  if (visible.value) {
    handleInitModel();
    restoreValidation();
  }
});

const closeModal = () => {
  visible.value = false;
};
const submitAddNotice = async (params: NoticeVO) => {
  const { error, data } = await addNotice(params);
  loading.value = false;
  if (!error) {
    (window as any).$message?.success(data?.msg);
    closeModal();
    emit('submitted');
  }
};
const submitEditNotice = async (params: NoticeVO) => {
  const { error, data } = await editNotice(params);
  loading.value = false;
  if (!error) {
    (window as any).$message?.success(data?.msg);
    closeModal();
    emit('submitted');
  }
};
async function handleSubmit(status: string) {
  await validate();
  loading.value = true;
  const { ...params } = model;
  if (!props.currentId) {
    if (params.filterType === '5') {
      const result = params.filterCondition
        .match(/\d+/g) // 匹配所有数字
        .map(Number); // 转换为数字
      params.filterCondition = result;
    }
    await submitAddNotice({ ...params, status } as unknown as NoticeVO);
  } else {
    await submitEditNotice({ ...params, id: props.currentId } as unknown as NoticeVO);
  }
}
const roleList = ref<Array<RoleVO>>([]);
const postList = ref<PostVO[]>([]);
const deptData = ref<Array<DeptVO>>([]);
const selectLoading = ref<boolean>(false);
const userList = ref<Array<UserVO>>([]);
// 请求部门树
const deptOptions = async () => {
  selectLoading.value = true;
  const { data, error } = await deptTreeSelect();
  selectLoading.value = false;
  if (!error) {
    deptData.value = data.data;
  }
};
const roleOptions = async () => {
  selectLoading.value = true;
  const { data, error } = await optionSelect([]);
  selectLoading.value = false;
  if (!error) {
    roleList.value = data?.data;
  }
};
const postOptions = async () => {
  selectLoading.value = true;
  const { error, data } = await postSelect();
  selectLoading.value = false;
  if (!error) {
    postList.value = data.data;
  }
};
const handleSearchMention = async (pattern: string) => {
  if (pattern) {
    selectLoading.value = true;
    // console.log(pattern, prefix);
    const { data, error } = await getAllUsers({ userName: pattern });
    selectLoading.value = false;
    if (!error) {
      // @ts-expect-error 忽略错误12312312
      userList.value = data?.data?.map((item: UserVO) => {
        return {
          label: item.userName,
          avatar: item?.avatar,
          value: item.userId
        };
      });
      // userList.value = data?.data;
      // console.log(data);
    }
  }
};
const debouncedSearch = useDebounce(handleSearchMention, 1000);
watch(
  () => model.filterType,
  () => {
    if (model.filterType === '2') {
      if (roleList.value.length <= 0) {
        roleOptions();
      }
    } else if (model.filterType === '6') {
      if (postList.value.length <= 0) {
        postOptions();
      }
    } else if (model.filterType === '3') {
      if (deptData.value.length <= 0) {
        deptOptions();
      }
    }
  }
);
const renderLabel = (option: any) => {
  return (
    <>
      <div class="w-180px flex flex-gap-10px flex-items-center">
        <NAvatar size={24} round={true} src={option.avatar} />
        {option.label}
      </div>
    </>
  );
};
</script>

<template>
  <NModal v-model:show="visible" :title="title" preset="card" class="w-740px">
    <NSpin :show="show">
      <NForm ref="formRef" :model="model" :rules="rules">
        <NGrid x-gap="12" responsive="screen" item-responsive>
          <NFormItemGi span="24 s:12 m:12" label="公告标题" path="noticeTitle">
            <NInput v-model:value="model.noticeTitle" placeholder="请输入公告标题" />
          </NFormItemGi>
          <NFormItemGi span="24 s:12 m:12" label="公告类型" path="noticeType">
            <NSelect
              v-model:value="model.noticeType"
              placeholder="请选择公告类型"
              :options="props.sysNoticeType"
              clearable
            />
          </NFormItemGi>
          <NFormItemGi span="24 s:12 m:12" label="筛选类型" path="filterType">
            <NSelect
              v-model:value="model.filterType"
              placeholder="请选择筛选类型"
              clearable
              :options="props.sysFilterType"
            />
          </NFormItemGi>
          <NFormItemGi v-if="model.filterType === '2'" span="24 s:12 m:12" label="角色" path="filterCondition">
            <NSelect
              v-model:value="model.filterCondition"
              label-field="roleName"
              multiple
              value-field="roleId"
              placeholder="请选择角色"
              :loading="selectLoading"
              clearable
              :options="roleList"
            />
          </NFormItemGi>
          <NFormItemGi v-else-if="model.filterType === '6'" span="24 s:12 m:12" label="岗位" path="filterCondition">
            <NSelect
              v-model:value="model.filterCondition"
              label-field="postName"
              multiple
              :loading="selectLoading"
              value-field="postId"
              placeholder="请选择岗位"
              clearable
              :options="postList"
            />
          </NFormItemGi>
          <NFormItemGi v-else-if="model.filterType === '3'" span="24 s:12 m:12" label="部门" path="filterCondition">
            <NTreeSelect
              v-model:value="model.filterCondition"
              filterable
              :loading="selectLoading"
              multiple
              :options="deptData"
              key-field="id"
              label-field="label"
              children-field="children"
            />

            <!-- :on-update:value="handleChangeDept" -->
          </NFormItemGi>
          <NFormItemGi v-else-if="model.filterType === '5'" span="24 s:12 m:12" label="指定用户" path="filterCondition">
            <NMention
              v-model:value="model.filterCondition"
              :options="userList"
              placeholder="输入@符号进行搜索用户"
              :render-label="renderLabel"
              separator=","
              :loading="selectLoading"
              @search="debouncedSearch"
            >
              <template #empty>
                <Empty />
              </template>
            </NMention>
          </NFormItemGi>
          <NFormItemGi span="24 s:12 m:12" label="通知方式" path="receiveMode">
            <NCheckboxGroup v-model:value="model.receiveMode">
              <NSpace item-style="display: flex;">
                <NCheckbox
                  v-for="(item, index) in props.sysReceiveMode"
                  :key="index"
                  :value="item.value"
                  :label="item.label"
                />
              </NSpace>
            </NCheckboxGroup>
          </NFormItemGi>
          <NFormItemGi span="24 s:12 m:12" label="永久有效" path="immortal">
            <NSpace align="center">
              <NSwitch v-model:value="model.immortal" checked-value="0" unchecked-value="1">
                <template #checked>是</template>
                <template #unchecked>否</template>
              </NSwitch>
              <NDatePicker
                v-if="model.immortal === '1'"
                v-model:formatted-value="model.deadline"
                require
                value-format="yyyy.MM.dd HH:mm:ss"
                type="datetime"
                clearable
              />
            </NSpace>
          </NFormItemGi>
          <NFormItemGi span="24 s:24 m:24" label="公告内容" path="noticeContent">
            <NInput v-model:value="model.noticeContent" type="textarea" placeholder="请输入公告内容" />
          </NFormItemGi>
        </NGrid>
      </NForm>
    </NSpin>

    <template #footer>
      <NSpace justify="end">
        <NButton @click="closeModal">取消</NButton>
        <NButton :loading="loading" @click="handleSubmit('2')">仅保存</NButton>
        <NButton type="primary" :loading="loading" @click="handleSubmit('1')">发布并保存</NButton>
      </NSpace>
    </template>
  </NModal>
</template>

<style lang="scss" scoped></style>
